home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
basic
/
pbasmlib.zip
/
EMS.DOC
< prev
next >
Wrap
Text File
|
1994-02-12
|
16KB
|
315 lines
PBASMLIB Assembly Language Routines for PB3C
Version 1.0
Expanded Memory (EMS) Module
(C) Copyright 1994 by Tim Gerchmez
All Rights Reserved.
This module interfaces you to EMS (Expanded Memory) in your computer,
if it is available and an EMS driver is loaded. You will be able to
access any or all of these routines by including the statements
$INCLUDE "PBASMLIB.INC" and $LINK "PBASMLIB.PBL" at the top of your
PowerBASIC programs. An interface to XMS (Extended Memory) is included
in a separate module.
Many of these commands let you access EMS memory at a very low level. For
an easier way to access EMS memory, see EMSPUTSTRING and EMSGETSTRING.
PowerBASIC is an ideal language to use EMS with because of its ability
to utilize absolute arrays. EMS memory is mapped into a section of memory
physically accessible to the CPU, and you can map a PowerBASIC array into
this "Page Frame" segment for direct access to EMS! Just use the EMSPAGEFRAME
function to find the page frame segment, then DIM an ABSOLUTE array AT the correct
segment of memory (see the PB online help for further information on the DIM ABSOLUTE
array AT sequence). The following is an example:
pf?? = emspageframe 'Get the EMS page frame in your system
dim absolute arry%(0 to 32767) at pf?? 'DIM an integer array at page frame.
'You are not restricted to an integer
'array, but could use byte or word arrays
'(or other numerics) instead. Integers are
'convenient because they are fast, easy to
'manipulate, and use two bytes per number,
'which fills the 64K page frame perfectly
'(32768 * 2 = 64K).
The newest versions of MS-DOS include Expanded/Extended Memory drivers that
let you use EMS or XMS interchangeably (they fool the program into thinking
that a large quantity of both is available, while one or the other "decreases"
as the other kind of memory is used). Given the choice, and given PowerBASIC's
ability to use DIM ABSOLUTE for arrays, it's recommended that you use EMS memory
whenever possible. You can, however, use either or both with modern versions of
DOS and computers that contain XMS memory and a memory manager that emulates EMS
memory.
Caution: PB does not seem to like you playing with EMS memory while in the
IDE. I have gotten EMM386 error #12, followed by an automatic reboot,
when accessing EMS while in the IDE. You might test this on your system
to see if you get the same results. If you do, be sure to use EMS routines
only in a standalone .EXE file.
The following is a list of error codes that may be returned
by function EMSERROR:
128 Internal error in EMM software 146 Source and target overlap
129 Malfunction in EMS hardware 147 Illegal region length
130 Memory manager busy 148 Region overlap
131 Invalid handle 149 Offset outside logical page
132 Function not defined 150 Region length > 1MB
133 No more handles available 151 Cannot exchange overlap
134 Error in mapping context 152 Memory types undefined
135 Not enough pages exist 153 Not used
136 Not enough pages available 154 ARS not supported
137 Cannot allocate zero pages 155 ARS currently allocated
138 Page not allocated to handle 156 ARS not zero
139 Illegal physical page number 157 ARS not allocated
140 Save state area full 158 DMA channels not supported
141 Save of mapping context failed 159 Illegal DMA channel
142 Restore of mapping context failed 160 No handle for this name
143 Subfunction parameter not defined 161 Name already exists
144 Attribute type not defined 162 Memory address wrap
145 Feature not supported 163 Invalid pointer
240 String too long (EMS Module Internal)
================================================================================
function emsactivehandles
Returns the number of currently active EMS handles in use.
The number of active EMM handles will never exceed 255. If
this function encounters an error, it can be checked with EMSERROR.
Example: print emsactivehandles
================================================================================
sub emsalloc(pg??,h??)
Allocates a certain number of EMS pages (16K per page), and returns
a handle to be used in future accesses to those pages. Be sure to
check if there's any EMS available with EMSFREE first, and use the
function EMSERROR afterwards to make sure there was no error encountered.
pg??: Set to total number of EMS pages (16K per page) to allocate
h??: Returns a handle if allocation was successful, or zero/
undefined if error (see example below).
Example: emsalloc 2,h?? 'Allocates 32K of memory (2 16K pages)
if emserror = 0 then print "32K EMS allocated successfully."
================================================================================
sub emsdealloc(h??)
Deallocates (releases) the EMS pages currently assigned to a
handle, and releases the handle itself. Call this function when
you are done using a certain section of EMS. It is important to
deallocate ALL EMS allocated with EMSALLOC before ending your program,
or that memory will REMAIN allocated until the computer is rebooted.
Use function EMSERROR to check the status of this command after using it.
You can also use this command to deallocate EMS strings allocated with
EMSPUTSTRING (see this command for details).
h??: Set to the handle to deallocate (originally returned with EMSALLOC).
Example: call emsdealloc(h??) 'Deallocates handle h??
================================================================================
function emsdetect
This function checks to see whether an expanded memory manager
(EMM) is installed. It does not check to see whether the EMM is
activated, or whether EMS memory is actually available. Use this
function first before calling any of the other functions, as an EMM
driver is a necessity in using Expanded Memory. This function will
also detect whether an XMS/EMS driver allows EMS (for example, if the
NOEMS option is set with EMM386, zero (not installed) will be returned).
Note: For those techies who are interested, this routine uses the
EMMXXXX0 filename method, with a call to IOCTL output status request
for extra security.
emsdetect: Returns -1 if Expanded Memory Manager is resident, or 0 if not.
Example: if emsdetect then print "EMM detected."
================================================================================
function emserror
Returns the status of the last EMS function performed in
the EMS unit. Will return a zero if no error, or error
code if error (see listing of possible error codes elsewhere
in this document). Check the status of EMSERROR after every
EMS function that could encounter an error.
Example: if emserror then print "EMS Error!":stop
================================================================================
function emsfree
Returns total number of 16K EMS pages free. To find out TOTAL
number of EMS pages instead, use EMSTOTAL. Returns -1 if error
is encountered, which you can check with EMSERROR.
Example: print (16384*emstotal) "Bytes EMS free."
================================================================================
function emsgetstring$(h??)
Retrieves a string previously stored in EMS with EMSPUTSTRING,
and deallocates the associated handle. This routine, or EMSDEALLOC,
must eventually be called after EMSPUTSTRING, or the EMS will remain
allocated until the computer is rebooted. Many errors may be encountered
in the retrieval process, so be sure to check with EMSERROR after
using this function to be sure the string was recalled properly.
See EMSPUTSTRING for details on how to use that function.
h??: Set to handle previously returned by EMSPUTSTRING. Deallocates
handle h?? if everything goes correctly (it should). If you get
an error with this routine, you may want to call EMSDEALLOC separately
to be sure handle h?? is deallocated.
emsgetstring$: Returns the string originally passed to EMSPUTSTRING.
Example: s$ = emsgetstring$(h??)
if emserror = 0 the print "String Retrieved."
if emserror <> 0 then call emsdealloc(h??) 'Insurance
================================================================================
sub emsmap(mp??,ep??,h??)
Maps a logical EMS page (16K) onto one of the four physical
pages (16K apiece) in the EMS page frame, effectively storing
the EMS page to the physical page, and associating it with any
changes then made to that physical page. This concept of "mapping"
can be more confusing than a simple store to/recall from concept,
so let's go over it. When you map an EMS page to a physical memory
page, the contents of the EMS page are first moved INTO the physical
page. Think of the physical page as being soft like wet concrete, and
the EMS page being a metal mold. That EMS page then "softens" and remains
"on top of" the physical memory page, conceptually changing along with the
physical contents every time you write to the physical page. When you call
this function again to map a NEW EMS page to the current physical page, the
current EMS page is "lifted off of" the physical page and retains its "imprint."
The new EMS page is then "imprinted" into the physical memory, and the process
starts over. It may help to envision this process in your mind as you read this.
XMS storage is more straightforward in some ways than EMS storage (it uses a normal
store/recall technique rather than the concept of "memory mapping." Examples of EMS
mapping are included as source code files with PBASMLIB, as a demonstration.
mp??: Set to the Physical Page Number (0-3) in the page frame to map EMS to.
Remember, each physical page is 16K in size.
ep??: Set to the EMS page (each logical page is 16K in length) to map onto the
physical page you specified in mp??. This number should be in the range
of 0 to N-1, where N is the number of pages previously allocated to the
EMM handle with the EMSALLOC function (next parameter).
h??: Set to the EMS handle associated with the pages you're mapping to physical
memory.
To actually access the physical page frame memory, use function EMSPAGEFRAME
to find the EMS page frame segment address. You can then use DEF SEG along with
PEEK and POKE, or DIM an ABSOLUTE array AT the value returned by EMSPAGEFRAME.
Note: Be sure to use EMSERROR to check if an error occurred after using this routine.
Example: emsmap 0,85,h?? 'Maps EMS page 85 of handle h?? onto page frame page 0.
================================================================================
function emsowned(h??)
Returns the number of 16K EMS pages allocated to a particular
handle. An EMM handle never has zero pages of memory allocated
to it. If an error occurs with this routine (invalid handle, for
example), the value 0 will be returned, and error number can be
checked with EMSERROR.
Example: print emsowned(h??)
================================================================================
function emspageframe
Returns the physical segment of memory the EMM manager maps
EMS memory to. This will be the area of memory to retrieve
data from once EMS is mapped there. The EMS page frame area
is 64K in size, and starts at offset zero of the segment
returned by this function. It consists of four 16K "pages"
that 16K EMS pages can be mapped on to (see EMSMAP). If 0 is
returned by this function, an error was encountered, which you
should check with function EMSERROR.
Example: print emspageframe
================================================================================
sub emsputstring(s$,h??)
Saves a string in EMS memory, and returns a handle for later
retrieval of the string. This is one of the easiest to use EMS
routines in the PBASMLIB EMS unit, and requires only that
you check for the presence of an EMS driver with EMSDETECT.
The routine will check for free EMS memory, allocate a handle
for you, and store the string in EMS. Many errors can be
encountered along the way, so BE SURE TO CHECK after calling
this routine with the EMSERROR function. EMSERROR will return
a value of zero if the function was successful, or an error number
listed at the top of this document.
NOTE: This routine uses physical page zero (and 1 if needed) of the page
frame, and maps its own handle's EMS onto that page. You may need to
remap your EMS pages back if you're using EMS independent of this routine.
s$: Set to string to store, up to a maximum of 32,750 bytes in
length (make sure to set the $STRING metastatement appropriately).
Each string passed will be allocated a handle and a FULL 16K of
EMS memory AT LEAST, so the longer the string, the less memory will
be wasted (at each 16K boundary). Note that a string longer than 16K
will be allocated 32K of EMS memory. It is suggested that you group
smaller strings into one long string, use emsputstring, get the string
back later with EMSGETSTRING, then parse the string back out.
h??: Returns an EMS handle for later retrieval of the passed string, if
everything worked correctly. If not, h?? will be undefined.
Note that you must eventually either (1) use EMSGETSTRING to retrieve
the string (this deallocates handle h?? automatically), or use EMSDEALLOC
to deallocate h??, or the handle will remain allocated until the computer
is rebooted.
Example: s$="This is a test" 'Short string, lots of EMS wasted
emsputstring s$,h?? 'Save the string
if emserror = 0 then print "S$ was stored in EMS memory."
if emserror <> 0 then print "EMS Error Number";emserror : end
s$="" 'Deallocate s$, now that it's in EMS.
================================================================================
function emsstatus
This function checks whether the installed EMS hardware is
functioning properly. Be sure to check for the existence of
an expanded memory manager with EMSDETECT before calling this
function. This function should generally return an ok status
with EMS emulators like EMM386, since XMS hardware is used to
emulate the presence of EMS memory.
emsstatus: Returns -1 if hardware ok, or 0 if error (use EMSERROR
to check error code if a zero is returned).
Example: if emsstatus = -1 then print "EMS hardware is ok."
================================================================================
function emstotal
Returns the total number of logical EMS pages present in the
system (NOT FREE pages). Each EMS page is 16K in size. To
find number of pages free, use EMSFREE instead. Returns -1 if
error occurs, which you can check with EMSERROR.
Example: tot?? = emstotal
================================================================================
function emsversion
Returns the version number of the EMM driver currently
installed. The version number is encoded as BCD, and can
be converted by using the HEX$() equivalent (see examples below).
If an error is encountered (unlikely), it can be checked with EMSERROR.
Example: print hex$(emsversion) 'Version 4.x of EMM386 prints "40"
Example: v% = val(hex$(emsversion)) 'Get version number in a numeric variable